<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>

  </style>
</head>

<body>
  <script>
    function Father() {
      this.name = ['父类属性1', '父类属性2']
      this.say1 = function () {
        console.log('属性函数');
      }
      Father.prototype.say2 = function (m) {
        // console.log('原型父类说话');
        this.name.push(m)
      }
    }
    // 1. 构造函数继承
    /*
    优：继承父类的属性和方法
    缺：不会继承父类的原型属性和原型方法
    */
    // function Son(){
    //   // 让父类中的this指向子类实例
    //   Father.call(this)
    // }

    // let son1=new Son()
    // son1.name.push('son1实例添加的属性')
    // console.log('son1',son1);
    // let son2=new Son()
    // son2.name.push('son2实例添加的属性')
    // console.log('son2',son2);


    // 2. 原型链继承
    /*
    优：继承父类的原型属性和原型方法
    缺：子类的所有实例保存的是同一个父类的值,子类修改父类时影响所有子类实例（无法实现多继承）
    */
    // function Son() { 

    // }

    // Son.prototype=new Father()

    // let son1=new Son()
    // let son2=new Son()


    // son1.say2('son1')
    // console.log('son1',son1); // 父类中的this.name=['父类属性1','父类属性2','son1']
    // console.log('son2',son2); // 父类中的this.name=['父类属性1','父类属性2','son1']

    // 3. 组合继承（结合构造函数继承和原型链继承）
    /*
    调用两次父类构造函数,占内存
    */
    // function Son() {
    //   Father.call(this)
    // }

    // Son.prototype = new Father()
    // Son.prototype.constructor = Son //重定向子类的constructor指向

    // 4. 寄生组合继承（推荐）
    // function Son() {
    //   Father.call(this);
    //   this.type = 'son'
    // }

    // Son.prototype = Object.create(Father.prototype); //创建一个对象，对象的__proto__指向父类原型prototype
    // Son.prototype.constrctor = Son;

    // 5. es6继承
    // 构造方法（父类）
    class Phone {
      constructor(brand, price) {
        this.brand = brand;
        this.price = price;
      }

      // 父类的成员属性
      call() {
        console.log("我可以打电话");
        console.log("我的品牌是："+this.brand);
      }
    }

    // 子类 extends继承
    class SmartPhone extends Phone {
      // 构造方法
      constructor(brand, price, color, size) {
        // 构造方法中第一句super，实现call继承的功能(让父类中的this指向子类实例)——继承父类的属性
        super(brand, price);

        this.color = color;
        this.size = size;
      }

      photo() {
        console.log("拍照");
      }

      playGame() {
        console.log("玩游戏");
      }
      // 对父类方法进行重写
      // call(){
      //   console.log("我可以打视频电话");
      // }
    }

    // 子类实例化
    const xiaomi = new SmartPhone('小米', 1999, '红色', '4.7inch');
    console.log(xiaomi);
    xiaomi.call() //调用父类中的call方法
  </script>
</body>

</html>